package com.milepost.workflow.attach.ctrl;

import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSONObject;
import com.milepost.workflow.attach.entity.FlowAttachEntity;
import com.milepost.workflow.attach.service.FlowAttachService;
import com.milepost.workflow.response.Response;
import com.milepost.workflow.response.ResponseHelper;
import com.milepost.workflow.util.SessionUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;

/**
 * @author huarf
 * @Description
 * @create 2022-04-03 16:50
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/attach")
public class AttachCtrl {

    @Value("${attach.position}")
    private String attachPosition;

    private final FlowAttachService flowAttachService;

    /**
     * 上传附件
     *
     * @param multipartFileList
     * @param flowAttachEntity
     * @return
     */
    @PostMapping("upload")
    public Response<?> upload(@RequestParam("files") List<MultipartFile> multipartFileList,
                              FlowAttachEntity flowAttachEntity, HttpSession session) {

        Response<?> response = null;

        try {
            flowAttachEntity.setUploadUser(SessionUtil.getCurrUser(session).getId());
            boolean success = flowAttachService.upload(multipartFileList, flowAttachEntity);
            if (success) {
                response = ResponseHelper.createSuccessResponse();
                response.setMsg("上传附件成功");
            } else {
                response = ResponseHelper.createFailResponse();
                response.setMsg("上传附件失败");
            }
        } catch (Exception e) {
            log.error("上传附件异常", e);
            response = ResponseHelper.createExceptionResponse(e);
        }

        return response;
    }

    /**
     * 下载附件
     *
     * @param id
     * @throws IOException
     */
    @GetMapping(value = "download")
    public void download(String id, HttpServletResponse response) {

        InputStream inputStream = null;
        OutputStream outputStream = null;

        try {
            //查询附件数据
            FlowAttachEntity flowAttachEntity = flowAttachService.getById(id);
            if (flowAttachEntity == null) {
                response.setContentType("application/json");
                Response<String> exceptionResponse = ResponseHelper.createExceptionResponse(new RuntimeException("文件不存在"));
                writeToResponse(response, exceptionResponse);
            } else {
                response.setContentType(flowAttachEntity.getContentType());
                response.setContentLengthLong(flowAttachEntity.getSize());
                response.setCharacterEncoding("utf-8");
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(flowAttachEntity.getName(),"UTF-8") + "." + flowAttachEntity.getExt());
                inputStream = new FileInputStream(new File(attachPosition + File.separator +
                        flowAttachEntity.getPath() + File.separator +
                        flowAttachEntity.getHash() + "." + flowAttachEntity.getExt()));
                outputStream = response.getOutputStream();

                FileCopyUtils.copy(inputStream, outputStream);
            }

        } catch (Exception e) {
            log.error("下载附件异常", e);
        } finally {
            IoUtil.close(inputStream);
            IoUtil.close(outputStream);
        }
    }

    /**
     * 将 Response 对象写入到 response 中
     *
     * @param servletResponse
     * @param response
     * @throws IOException
     */
    protected void writeToResponse(ServletResponse servletResponse, Response<String> response) throws IOException {

        HttpServletResponse res = (HttpServletResponse) servletResponse;
        //设置Content-Type
        res.setContentType("application/json;charset=UTF-8");
        //设置charset
        res.setCharacterEncoding("UTF-8");
        //写入
        PrintWriter writer = res.getWriter();
        writer.write(JSONObject.toJSONString(response));
    }
}
